<?php

class CustStocksInController extends AppController {

    var $name = 'CustStocksIn';

    const STOCK_IN_TYPE = 'S';

    var $pageTitle = 'Stock in Inventory';
    var $viewPath = 'customers/stocks_in/stocks_in';
    var $uses = array('CustStockInHead', 'Dispatch', 'SDH', 'SD', 'CustStockIn', 'CustProductSite', 'Customer', 'RunningNo', 'Site', 'User', 'ProductSerial', 'CustLocation', 'Supplier', 'CustomerSupplier', 'CPSLocation');
    var $paginate = array(
        'CustStockInHead' => array(
            'order' => 'CustStockInHead.id DESC'
        )
    );
    var $components = array('Email');

    function beforeFilter() {
        parent::beforeFilter();
        $this->set('parentNav', 'cust_stocks_in');
        $this->_checkPrintView();
    }

    function display() {
        parent::display('CustStockInHead');
        $this->paginate['CustStockInHead']['contain'] = array('Dispatch', 'SDH', 'Supplier');

        $this->_checkSite('CustStockInHead');

        $this->_checkBetweenSearch('CustStockInHead', 'stock_in_date');

        $this->_paging('CustStockInHead', array(
            'stock_in_no' => 'LIKE'
        ));
    }

    function save() {
        $cust_stock_in_head_id = null;
        if (!empty($this->data)) {

            // เรียงลำดับรายการใหม่ กรณีลบแถว Index เปลี่ยน
            $this->adjustRowIndex($this->data['CustStockIn']);

            // ตรวจสอบว่ามีสินค้าอยู่ในใบ ItsStockInHead
            if (count($this->data['CustStockIn']) == 0) {
                $this->Session->setFlash("Stock in must have at least one product !!!.", 'flash/fail');
                unset($this->data);
            } else {
                $this->CustStockInHead->query("BEGIN");
                $is_success = true;
                $collector_id = $this->Auth->user('id');
                $dispatch_from = $this->data['CustStockInHead']['dispatch_from'];

                if ($dispatch_from == ITS_PREFIX) {
                    $this->_update_its_dispatch_status();
                    $this->Dispatch->id = $this->data['CustStockInHead']['dispatch_id'];
                    $dispatch_no = $this->Dispatch->field('dispatch_no');
                } else {
                    $this->data['CustStockInHead']['dispatch_id'] = $this->data['CustStockInHead']['supplier_dispatch_id'];
                    $this->_update_supplier_dispatch_status();
                    $this->SDH->id = $this->data['CustStockInHead']['dispatch_id'];
                    $dispatch_no = $this->SDH->field('dispatch_no');
                }

                // กำหนดข้อมูล Cust Stock in head
                // Generate stock in no
                $this->Customer->id = $this->Auth->user('customer_id');
                $cust_no = $this->Customer->field('cust_no');
                $this->Site->id = $this->Auth->user('site_id');
                $site_no = $this->Site->field('site_no');

                // เอาเฉพาะ Running no ของ dispatch จาก ITS52000001 => 52000001
                $runno = substr($dispatch_no, 3, 10);
                $this->data['CustStockInHead']['stock_in_no'] = $cust_no . '-' . $site_no . '-' . RunningNo::STOCK_IN_TYPE . '-' . $runno;

                $this->data['CustStockInHead']['customer_id'] = $this->Auth->user('customer_id');
                $this->data['CustStockInHead']['site_id'] = $this->Auth->user('site_id');
                $this->data['CustStockInHead']['collector_id'] = $this->Auth->user('id');

                // ตรวจสอบ data ที่เข้ามาให้ถูกต้อง
                $this->CustStockIn->validate['cust_location_id'] = array('rule' => 'notEmpty', 'message' => 'Please select a location.');

                if ($this->CustStockInHead->saveAll($this->data, array('validate' => 'first', 'atomic' => false)) == true) {    // ถ้าไม่ใช่จะ return array error field
                    $dispatch_id = $this->data['CustStockInHead']['dispatch_id'];
                    $cust_stock_in_head_id = $this->CustStockInHead->id;

                    foreach ($this->data['CustStockIn'] as $csi) {

                        $this->CustStockIn->contain();
                        $CS = $this->CustStockIn->find('first', array('conditions' => array('CustStockIn.product_id' => $csi['product_id'], 'CustStockIn.cust_stock_in_head_id' => $cust_stock_in_head_id)));
                        $csi_id = $CS['CustStockIn']['id'];
                        $this->CustStockIn->id = $csi_id;

                        // Update Cust Product Site current stock
                        $stock_in_qty = $csi['stock_in_qty'];
                        $this->CustProductSite->id = $csi['cust_product_site_id'];
                        $this->CustStockIn->saveField('replenish_date', $this->CustProductSite->field('replenish_date'));
                        $this->CustStockIn->saveField('current_stock', $this->CustProductSite->field('current_stock'));
                        $this->CustProductSite->addCurrentStock($this->CustProductSite->id, $stock_in_qty);

                        if ($dispatch_from == ITS_PREFIX) {
                            $this->_update_its_product_serials($csi, $csi_id, $stock_in_qty);
                        } else {
                            // บันทึก ราคาที่ Vendor ส่งเข้ามาในตาราง CustProductSite
                            $this->CustStockIn->saveField('quotation_price',
                                    $this->SD->field('price', array(
                                        'supplier_dispatch_head_id' => $this->data['CustStockInHead']['dispatch_id'],
                                        'product_id' => $csi['product_id']
                                            )
                            ));
                            $this->_update_supplier_product_serials($csi, $csi_id, $stock_in_qty);
                        }
                    }
                } else {
                    $is_success = false;
                }
                if ($is_success) {
                    $this->CustStockInHead->query("COMMIT");
                    ;
                    $cust_stock_in_head_id = $this->CustStockInHead->id;
                    $this->_sendEmail($cust_stock_in_head_id);
                    $this->Session->setFlash("Stock in no {$this->data['CustStockInHead']['stock_in_no']} save succesfull.", 'flash/ok');
                } else {
                    $this->CustStockInHead->query("ROLLBACK");
                    $this->Session->setFlash("Stock in save fail!!!.", 'flash/fail');
                }
            }
        }
        $this->data['CustStockIn'] = null;
        $this->setAction('view', $cust_stock_in_head_id);
    }

    /**
     * ปรับสถานะใบ Dispatch ตามจำนวน Product ที่ stock in
     */
    function _update_its_dispatch_status() {
        $dispatch_id = $this->data['CustStockInHead']['dispatch_id'];
        // ดึงรายการทั้งหมดที่อยู่ใน Dispatch ใบนี้ (รวมที่ไม่ได้ stock in)
        $this->CustStockIn->contain();
        $custStocksIn = $this->CustStockIn->find('all', array(
                    'conditions' => array(
                        'dispatch_id' => $dispatch_id,
                    ),
                        )
        );

        // (ตรงนี้ยากที่สุดเลย T_T 3/4/52)
        // เรียงลำดับ Cust stock in ที่ป้อนเข้ามาใหม่ ให้เหมือนลำดับที่เก็บในฐานข้อมุล
        sort($this->data['CustStockIn']);

        $dispatch_status_id = DispatchStatus::CONSIGNED_STATUS;
        $custStockInCount = count($custStocksIn);
        for ($d = 0, $c = 0; $c < $custStockInCount; ++$d, ++$c) {

            // มีรายการอยู่ยังไม่หมดแถวที่ stock in เข้ามา
            if (isset($this->data['CustStockIn'][$d])) {

                // ถ้า cust stock in id ตรงกัน ทำการ stock in ถ้าไม่ dispatch status เป็น cancel
                if ($this->data['CustStockIn'][$d]['id'] > $custStocksIn[$c]['CustStockIn']['id']) {
                    // สินค้ารายการนี้ไม่ถูก Stock in
                    $this->CustStockIn->id = $custStocksIn[$c]['CustStockIn']['id'];
                    $this->CustStockIn->saveField('dispatch_status_id', DispatchStatus::CANCEL_STATUS);
                    // สถานะใบ dispatch เป็น partial consigned
                    $dispatch_status_id = DispatchStatus::PARTIAL_CONSIGNED_STATUS;
                    --$d;
                } elseif ($this->data['CustStockIn'][$d]['id'] == $custStocksIn[$c]['CustStockIn']['id']) {
                    // Stock in
                    $stock_in_qty = $this->data['CustStockIn'][$d]['stock_in_qty'];
                    $this->data['CustStockIn'][$d]['current_qty'] = $stock_in_qty;
                    $this->data['CustStockIn'][$d]['stock_out_qty'] = 0;

                    // ตรวจสถานะการ stock in
                    // ถ้าจำนวนรับเข้า ไม่เท่ากับ จำนวนที่ส่ง สถานะ dispatch และ custStockIn เป็น partial
                    if ($stock_in_qty == $custStocksIn[$c]['CustStockIn']['deliver_qty']) {
                        $this->data['CustStockIn'][$d]['dispatch_status_id'] = DispatchStatus::CONSIGNED_STATUS;
                    } else {
                        $this->data['CustStockIn'][$d]['dispatch_status_id'] = DispatchStatus::PARTIAL_CONSIGNED_STATUS;
                        // ปรับสถานะใบ dispatch เป็น partial
                        $dispatch_status_id = DispatchStatus::PARTIAL_CONSIGNED_STATUS;
                    }
                } else {
                    //debug($this->data['CustStockIn'][$d]);
                    // ไม่น่าเกิดทางเลือกนี้
                }
            } else {
                // สินค้ารายการนี้ไม่ถูก Stock in
                --$d;
                $this->CustStockIn->id = $custStocksIn[$c]['CustStockIn']['id'];
                $this->CustStockIn->saveField('dispatch_status_id', DispatchStatus::CANCEL_STATUS);
                // สถานะใบ dispatch เป็น partial consigned
                $dispatch_status_id = DispatchStatus::PARTIAL_CONSIGNED_STATUS;
            }
        }
        // ปรับ Dispatch Status
        $this->Dispatch->id = $dispatch_id;
        $this->Dispatch->saveField('dispatch_status_id', $dispatch_status_id);
    }

    /**
     * ปรับสถานะใบ Supplier Dispatch ตามจำนวน Product ที่ stock in
     */
    function _update_supplier_dispatch_status() {
        // สถานะ dispatch เริ่มต้น
        $dispatch_status_id = DispatchStatus::CONSIGNED_STATUS;
        $sdh_id = $this->data['CustStockInHead']['supplier_dispatch_id'];

        // ดึงจำนวนรายการที่ส่งเข้ามาในใบ Supplier Dispatch ถ้าจำนวนไม่ตรงกับที่ stock in สถานะเป็น partial
        $this->SD->contain();
        $sd_count = $this->SD->find('count', array('conditions' => array('supplier_dispatch_head_id' => $sdh_id)));
        $csi_count = count($this->data['CustStockIn']);

        if ($sd_count != $csi_count) {
            $dispatch_status_id = DispatchStatus::PARTIAL_CONSIGNED_STATUS;
        }

        // แต่ละรายการที่ stock in
        foreach ($this->data['CustStockIn'] as &$csi) {
            $dispatch_status_id_line = DispatchStatus::CONSIGNED_STATUS;

            // ดึงรายการ Supplier Dispatch
            $this->SD->contain();
            $sd = $this->SD->find('first', array('conditions' => array('SD.product_id' => $csi['product_id'], 'supplier_dispatch_head_id' => $sdh_id)));

            // ถ้าจำนวน ที่ stock in ไม่เท่าจำนวนที่ส่งมา สถานะ dispatch เป็น partial
            if ($sd['SD']['qty'] != $csi['stock_in_qty']) {
                $dispatch_status_id = DispatchStatus::PARTIAL_CONSIGNED_STATUS;
                $dispatch_status_id_line = DispatchStatus::PARTIAL_CONSIGNED_STATUS;
            }

            $this->SD->id = $sd['SD']['id'];
            $this->SD->saveField('stock_in_qty', $csi['stock_in_qty']);
            $csi['dispatch_status_id'] = $dispatch_status_id_line;
        }

        // ปรับ Dispatch Status
        $this->SDH->id = $sdh_id;
        $this->SDH->saveField('dispatch_status_id', $dispatch_status_id);
    }

    function _update_its_product_serials($csi, $csi_id, $stock_in_qty) {

        $this->ProductSerial->contain();
        $PSs = $this->ProductSerial->find('all', array(
                    'conditions' => array(
                        'its_stock_out_id' => $csi['id'],
                        'its_stock_out_type' => CustStockIn::ITS_STOCK_OUT_TYPE
                    ),
                    'limit' => $stock_in_qty,
                    'order' => 'stock_out_priority'
                        )
        );

        // update รายการ Product Serial
        for ($i = 0; $i < $stock_in_qty; ++$i) {
            $data = array();
            $data['ProductSerial']['id'] = $PSs[$i]['ProductSerial']['id'];
            $data['ProductSerial']['cust_stock_in_id'] = $csi_id;
            $data['ProductSerial']['cust_stock_in_type'] = CustStockIn::CUST_STOCK_IN_TYPE;
            $data['ProductSerial']['cust_location_id'] = $csi['cust_location_id'];
            $this->ProductSerial->create();
            $this->ProductSerial->save($data);
            $this->CPSLocation->addLocation($csi['cust_product_site_id'], $data['ProductSerial']['cust_location_id']);
        }
    }

    function _update_supplier_product_serials($csi, $csi_id, $stock_in_qty) {

        $this->ProductSerial->contain();
        $PSs = $this->ProductSerial->find('all', array(
                    'conditions' => array(
                        'its_stock_out_id' => $csi['its_stock_out_id'],
                        'its_stock_out_type' => SD::ITS_STOCK_OUT_TYPE
                    ),
                    'limit' => $stock_in_qty,
                    'order' => 'stock_out_priority'
                        )
        );

        // update รายการ Product Serial
        for ($i = 0; $i < $stock_in_qty; ++$i) {
            $data = array();
            $data['ProductSerial']['id'] = $PSs[$i]['ProductSerial']['id'];
            $data['ProductSerial']['cust_stock_in_id'] = $csi_id;
            $data['ProductSerial']['cust_stock_in_type'] = CustStockIn::CUST_STOCK_IN_TYPE;
            $data['ProductSerial']['cust_location_id'] = $csi['cust_location_id'];
            $this->ProductSerial->create();
            $this->ProductSerial->save($data);
            $this->CPSLocation->addLocation($csi['cust_product_site_id'], $data['ProductSerial']['cust_location_id']);
        }
    }

    function _sendEmail($cust_stock_in_head_id) {
        $userName = $this->Auth->user('name');
        $this->Customer->id = $this->Auth->user('customer_id');
        $customerName = $this->Customer->field('name');
        $this->Site->id = $this->Auth->user('site_id');
        $siteName = $this->Site->field('name');
        $this->CustStockInHead->id = $cust_stock_in_head_id;

        // ส่ง e-mail กลับหา admin และ ผู้ดูแลแต่ละ customer (ถ้ามี)
        // นำรายชื่อผู้ที่ต้องการส่ง email ถึง ใส่ไว้ใน list
        $emailsTo = array();
//        $email_to = $this->requestAction('system_preferences/get/contact_email');
        $emailsTo[] = $this->requestAction('system_preferences/get/contact_email');
        $response_email = $this->Customer->field('response_email');

        if (!empty($response_email)) {
            $emailsTo[] = $response_email;
        }

        /**
         * ถ้าเป็นการ Stock in ที่ เป็น Other Vendor ส่ง Email หา Vendor ด้วย
         */
        if ($this->CustStockInHead->field('dispatch_from') == SUPPLIER_PREFIX) {
            $this->Supplier->id = $this->CustStockInHead->field('supplier_id');
            $emailsTo[] = $this->Supplier->field('email');
        }

        $this->set('userName', $userName);
        $this->set('customerName', $customerName);
        $this->set('siteName', $siteName);
        $this->set('cust_stock_in_head_id', $cust_stock_in_head_id);

        $emailFrom = "{$userName} {$customerName} {$siteName} <{$this->Auth->user('email')}>";
        $subject = 'VMI : Customer Stock In no ' . $this->CustStockInHead->field('stock_in_no');
        $template = 'customer/stock_in';

        $this->sendEmails($emailFrom, $emailsTo, $subject, $template);
    }

    function view($id = null) {
        $from_supplier = $this->Session->read('Auth.User.Extend.from_supplier');

        if ($id != null) {
            $this->CustStockInHead->contain(array('Customer', 'Site', 'Dispatch', 'Supplier', 'SDH',
                'CustStockIn' => array('Product' => array('part_no', 'supplier_part_no', 'text', 'Unit'), 'CustProductSite')));
            $this->data = $this->CustStockInHead->findById($id);
            $this->set('dispatchStatuses', $this->Dispatch->DispatchStatus->find('list', array(
                        'conditions' => array(
                            'id' => array(DispatchStatus::ON_DISPATCH_STATUS, DispatchStatus::CANCEL_STATUS)
                            ))));

            $this->_neighbors($id, $this->CustStockInHead, array('fields' => array('id', 'stock_in_no')));

            $this->set('mode', 'edit');
        } else {
            // เลือกรายการ dispatch ที่ยังไม่ได้ stock in
            $this->set('dispatches', $this->Dispatch->find('list', array(
                        'conditions' => array(
                            'Dispatch.site_id' => $this->Auth->user('site_id'),
                            'Dispatch.dispatch_status_id' => DispatchStatus::ON_DISPATCH_STATUS
                            )))
            );

            $conditions = array(
                'SDH.site_id' => $this->Auth->user('site_id'),
                'SDH.dispatch_status_id' => DispatchStatus::ON_DISPATCH_STATUS
            );
            if ($from_supplier == true) {
                $conditions['SDH.supplier_id'] = $this->Auth->user('supplier_id');
            }
            // เลือกรายการ Supplier dispatch ที่ยังไม่ได้ stock in
            $this->set('supplierDispatches', $this->SDH->find('list', array(
                        'conditions' => $conditions))
            );

            $this->set('stock_in_by', $this->Auth->user('name')); // กำหนดผู้ทำการ stock in
            $this->set('today', date("d/m/Y"));                 // กำหนด default วันที่ stock in
            $this->set('mode', 'add');
        }

        // เป็น Supplier เข้ามาใช้งานหรือไม่
        if ($from_supplier == true) {
            $this->Supplier->id = $this->Auth->user('supplier_id');
            $this->set('supplierName', $this->Supplier->field('name'));
        }
        $this->set('from_supplier', $from_supplier);
    }

    function print_view($id) {
        $this->layout = 'print';
        $this->data = $this->CustStockInHead->findForPrintById($id);
        $this->Customer->id = $this->data['CustStockInHead']['customer_id'];
        $this->set('see_current_stock', $this->Customer->field('see_stock_in_current_stock'));
    }

    /**
     * หา Product ตาม part no และ Dispatch id
     */
    function json_find_by_part_no_dispatch_id() {
        $this->RequestHandler->setContent('json');

        // ค้นหาข้อมูลโดย part no และ dispatch id
        $this->CustStockIn->contain(array('Product' => array('Unit'), 'CustProductSite'));
        $data = $this->CustStockIn->find('first', array('conditions' => array(
                        'OR' => array(
                            'Product.supplier_part_no' => $this->data['part_no'],
                            'Product.part_no' => $this->data['part_no'],
                            'CustProductSite.stock_code' => $this->data['part_no'],
                        ),
                        'dispatch_id' => $this->data['dispatch_id']
                        ))
        );

        $this->set('data', $data);
        // view เก็บอยู่ใน element
        $this->viewPath = 'elements';
        $this->render('ajax/json');
    }

    /**
     * หา Product ตาม supplier part no และ Dispatch id
     */
    function json_find_by_part_no_supplier_dispatch_id() {
        $this->RequestHandler->setContent('json');

        // ค้นหาข้อมูลโดย supplier part no และ dispatch id
        $this->SD->contain(array('Product' => array('Unit'), 'CustProductSite'));
        $data = $this->SD->find('first', array('conditions' => array(
                        'OR' => array(
                            'Product.supplier_part_no' => $this->data['part_no'],
                            'Product.part_no' => $this->data['part_no'],
                            'CustProductSite.stock_code' => $this->data['part_no'],
                        ),
                        'supplier_dispatch_head_id' => $this->data['dispatch_id']
                        ))
        );

        $this->set('data', $data);
        // view เก็บอยู่ใน element
        $this->viewPath = 'elements';
        $this->render('ajax/json');
    }

    /**
     * หา ProductSerial ตาม its_stock_out_id
     */
    function json_find_product_serials_by_its_stock_out_id() {
        $this->RequestHandler->setContent('json');

        $this->ProductSerial->contain();
        $data = $this->ProductSerial->find('all',
                        array(
                            'conditions' => array(
                                'its_stock_out_id' => $this->data['its_stock_out_id'],
                                'its_stock_out_type' => $this->data['its_stock_out_type'],
                            ),
                            'order' => 'stock_out_priority ASC'
                        )
        );

        $this->set('data', $data);
        // view เก็บอยู่ใน element
        $this->viewPath = 'elements';
        $this->render('ajax/json');
    }

    /**
     * หา Supplier จาก SDH id ที่เลือก
     */
    function json_supplier_by_dispatch_id() {
        $this->RequestHandler->setContent('json');

        $this->SDH->contain();
        $this->SDH->id = $this->data['sdh_id'];
        $supplier_id = $this->SDH->field('supplier_id');
        $this->Supplier->contain();
        $data = $this->Supplier->findById($supplier_id);

        $this->set('data', $data);
        // view เก็บอยู่ใน element
        $this->viewPath = 'elements';
        $this->render('ajax/json');
    }

    function popup_search() {
        parent::popup_search();
        $this->set('suppliers', $this->CustomerSupplier->listSupplierByCustomerId($this->Auth->user('customer_id'), array('has_cust_inventory' => true)));
        $this->set('popupWidth', 500);
    }

    /**
     * ถ้าเป็น Supplier เข้ามาดู ปรับ session ให้ add และ save ได้
     * @param <type> $read_only
     */
    function supplier_read_only($read_only) {
        $this->Session->write('Auth.User.read_only', $read_only);
    }

    function json_find_by_dispatch_id() {
        $this->layout = 'ajax';
        $this->Dispatch->contain(array('CustStockIn' => array('Product' => array('Unit'), 'CustProductSite')));
        $data = $this->Dispatch->findById($this->data['dispatch_id']);
        $this->set('data', $data);

        $this->viewPath = 'elements';
        $this->render('ajax/json');
    }

    function json_find_by_supplier_dispatch_id() {
        $this->layout = 'ajax';
        $this->SDH->contain(array('SD' => array('Product' => array('Unit'), 'CustProductSite')));
        $data = $this->SDH->findById($this->data['dispatch_id']);
        $this->set('data', $data);

        $this->viewPath = 'elements';
        $this->render('ajax/json');
    }

    /**
     * สำหรับ ITS เข้ามาแก้ราคา Cust Stock in
     * @param <type> $field
     * @param <type> $cust_stock_in_id
     */
    function inplace_editor_price($cust_stock_in_id) {
        $value = trim($this->params['form']['value']);
        parent::inplace_editor($this->CustStockIn, 'quotation_price', $cust_stock_in_id);

        // ตามไป update price ใน ProductSerial ด้วย
        $this->ProductSerial->updateAll(
                array('price' => $value),
                array('cust_stock_in_id' => $cust_stock_in_id, 'cust_stock_in_type' => CustStockIn::CUST_STOCK_IN_TYPE)
        );
    }

}

?>